package com.itmuch.contentcenter.service.content;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itmuch.contentcenter.dao.content.MidUserShareMapper;
import com.itmuch.contentcenter.dao.content.RocketmqTransactionLogMapper;
import com.itmuch.contentcenter.dao.content.ShareMapper;
import com.itmuch.contentcenter.domain.dto.content.ShareAuditDTO;
import com.itmuch.contentcenter.domain.dto.content.ShareDTO;
import com.itmuch.contentcenter.domain.dto.messaging.UserAddBonusDTO;
import com.itmuch.contentcenter.domain.dto.messaging.UserAddBonusMsgDTO;
import com.itmuch.contentcenter.domain.dto.user.UserDTO;
import com.itmuch.contentcenter.domain.entity.content.MidUserShare;
import com.itmuch.contentcenter.domain.entity.content.RocketmqTransactionLog;
import com.itmuch.contentcenter.domain.entity.content.Share;
import com.itmuch.contentcenter.feignclient.UserCenterFeignClient;
import com.itmuch.contentcenter.utils.JwtOperator;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.apache.rocketmq.spring.support.RocketMQHeaders;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.persistence.RollbackException;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ShareService {

    @Resource
    private JwtOperator jwtOperator;

    @Resource
    private ShareMapper shareMapper;

    @Resource
    private MidUserShareMapper midUserShareMapper;

    @Resource
    private RocketmqTransactionLogMapper rocketmqTransactionLogMapper;

    @Resource
    private RestTemplate restTemplate;

    @Resource
    private RocketMQTemplate rocketMQTemplate;

    @Resource
    private Source source;

    @Resource
    private DiscoveryClient discoveryClient;

    @Resource
    private UserCenterFeignClient userCenterFeignClient;

    public ShareDTO findById(Integer id){
        Share share = shareMapper.selectByPrimaryKey(id);
        Integer userId = midUserShareMapper.getUserIdByShareId(id);
//        List<String> targetUriList = discoveryClient.getInstances("user-center")
//                .stream()
//                .map(v->v.getUri().toString()+"/users/{id}")
//                .collect(Collectors.toList());
//                .findFirst()
//                .orElseThrow(IllegalArgumentException::new);
//        String targetUri = targetUriList.get(ThreadLocalRandom.current().nextInt(targetUriList.size()));

//        String targetUri = "http://user-center/users/{userId}";
//        UserDTO userDTO = this.restTemplate.getForObject(
//                targetUri,
//                UserDTO.class,userId
//        );

        UserDTO userDTO1 = this.userCenterFeignClient.findById(userId);
        System.out.println(userDTO1);

//        log.info("TargetUri://"+targetUri);
        System.out.println(share);
        ShareDTO shareDTO = new ShareDTO();
        BeanUtils.copyProperties(share,shareDTO);
//        assert userDTO != null;
        shareDTO.setWxNickname(userDTO1.getWxNickname());
        System.out.println(userDTO1);
        return shareDTO;
    }

//    public void testRestTemplate(){
//        ResponseEntity<String> forObject = this.restTemplate.getForEntity(
//                "http://localhost:8080/users/{id}",
//                String.class,3
//        );
//        System.out.println(forObject.getBody());
//        System.out.println(forObject.getStatusCode());
//    }

    public static void main(String[] args) {

    }

    public Share auditById(Integer id, ShareAuditDTO auditDTO) {
        // TODO 授权，认证
        //1.看看share存不存在， 不存在抛异常
        Share share = shareMapper.selectByPrimaryKey(id);
        if (share==null){
            throw new IllegalArgumentException("share不存在，抛异常");
        }
        //2.看看share的状态是否属于NOT_YET,不然抛异常
        if (!Objects.equals("NOT_YET",share.getAuditStatus())){
            throw new IllegalArgumentException("状态异常，抛异常");
        }
        //3.修改share的状态为传入参数通过或拒绝
//        auditByIdInDb(auditDTO, id);
        //4.如果是PASS，发送消息给RocketMQ,让用户中心去消费RocketMQ，并为发布人添加积分
        if (Objects.equals("PASS",auditDTO.getAuditStatusEnum().toString())){
            Integer userId = midUserShareMapper.getUserIdByShareId(id);
             this.source.output().send(
                     MessageBuilder.withPayload(UserAddBonusMsgDTO.builder()
                            .userId(userId)
                            .bonus(50)
                            .build())
                            .setHeader("share_id",id)
                            .setHeader(RocketMQHeaders.TRANSACTION_ID, UUID.randomUUID().toString())
                             .setHeader("dto", JSON.toJSONString(auditDTO))
                            .build()
         );
//            rocketMQTemplate.sendMessageInTransaction("tx_group",
//                    "add_bonus",
//                    MessageBuilder.withPayload(UserAddBonusMsgDTO.builder()
//                            .userId(userId)
//                            .bonus(50)
//                            .build())
//                            .setHeader("share_id",id)
//                            .setHeader(RocketMQHeaders.TRANSACTION_ID, UUID.randomUUID().toString())
//                            .build(),auditDTO
//            );
        }else {
            ShareService shareService = (ShareService) AopContext.currentProxy();
            shareService.auditByIdInDb(auditDTO,id);
        }
//            userCenterFeignClient.addBones(id,500);
        return share;
    }

    @Transactional(rollbackFor = Exception.class)
    public void auditByIdInDb(ShareAuditDTO auditDTO, Integer shareId) {
        Share share = Share.builder()
                .id(shareId)
                .auditStatus(auditDTO.getAuditStatusEnum().toString())
                .reason(auditDTO.getReason())
                .build();
        shareMapper.updateByPrimaryKeySelective(share);
    }


    @Transactional(rollbackFor = Exception.class)
    public void auditByIdInDbInLog(ShareAuditDTO auditDTO, Integer shareId,String transactionId) {
        this.auditByIdInDb(auditDTO,shareId);
        RocketmqTransactionLog rocketmqTransactionLog = RocketmqTransactionLog.builder()
                .transactionId(transactionId)
                .log("积分增加")
                .build();
        rocketmqTransactionLogMapper.insert(rocketmqTransactionLog);
    }

    public PageInfo<Share> q(String title, Integer pageNo, Integer pageSize, Integer userId) {
        PageHelper.startPage(pageNo,pageSize);
        List<Share> shares = this.shareMapper.selectByParam(title);
        List<Share> sharesDeal;
        if(userId == null) {
            sharesDeal=  shares.stream().peek(
             v->{
                v.setDownloadUrl(null);
             }).collect(Collectors.toList());
        }else {
            sharesDeal=  shares.stream().peek(
                    v->{
                        MidUserShare midUserShare = midUserShareMapper.selectOne(
                                MidUserShare.builder()
                                        .shareId(v.getId())
                                        .userId(userId)
                                        .build()
                        );
                        if (midUserShare == null) {
                            v.setDownloadUrl(null);
                        }
                    }
            ).collect(Collectors.toList());
        }

        return  new PageInfo<Share>(sharesDeal);
    }

    @Transactional(rollbackFor = Exception.class)
    public Share exchangeId(Integer id, HttpServletRequest request) {
        //1.查询share是否存在
        Share share = this.shareMapper.selectByPrimaryKey(id);
        if (share == null) {
            throw new IllegalArgumentException("抛出异常");
        }
        //2.查询mid_user_share是否存在
        Integer userId = (Integer) request.getAttribute("id");
        MidUserShare midUserShare = midUserShareMapper.selectOne(
                MidUserShare.builder()
                        .userId(userId)
                        .shareId(id)
                        .build());
        if (midUserShare != null) {
            return share;
        }
        //3.查询user是否够积分
        UserDTO userDTO = userCenterFeignClient.findById(userId);
        Integer price = share.getPrice();
        if(price > userDTO.getBonus()){
            throw new SecurityException("不够积分");
        }
        //4.扣减积分

        userCenterFeignClient.addBonus1(
                UserAddBonusDTO.builder()
                        .bonus(price)
                        .userId(userId)
                        .build()
        );

        //5.往mid_user_share插入一条记录
            midUserShareMapper.insertSelective(
                    MidUserShare.builder()
                    .shareId(id)
                    .userId(userId)
                    .build()
            );
        return share;
    }
}
